package com.miaocat19.service.impl;

import com.miaocat19.dao.PromoDOMapper;
import com.miaocat19.dataobject.PromoDO;
import com.miaocat19.error.BusinessException;
import com.miaocat19.error.EmBusinessError;
import com.miaocat19.service.ItemService;
import com.miaocat19.service.PromoService;
import com.miaocat19.service.UserService;
import com.miaocat19.service.model.ItemModel;
import com.miaocat19.service.model.PromoModel;
import com.miaocat19.service.model.UserModel;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @program: Javamiaosha
 * @description:
 * @author: miaocat19
 * @create: 2021-12-12 14:43
 **/
@Service
public class PromoServiceImpl implements PromoService {

    @Autowired
    private PromoDOMapper promoDOMapper;

    @Autowired
    private ItemService itemService;


    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserService userService;

    @Override
    public PromoModel getPromoByItemId(Integer itemId) {
        //获取对应商品的秒杀活动信息
        PromoDO promoDO = promoDOMapper.selectByItemId(itemId);

        //dataobject->model
        PromoModel promoModel = convertFromDataObject(promoDO);

        if (promoModel == null) {
            return null;
        }

        if (promoModel.getStartDate().isAfterNow()) {
            /*设置活动还没有开始*/
            promoModel.setStatus(1);
        } else if (promoModel.getEndDate().isBeforeNow()) {
            /*活动已经结束了*/
            promoModel.setStatus(3);
        } else {
            /*活动正在进行中*/
            promoModel.setStatus(2);
        }
        return promoModel;
    }


    @Override
    public void publishpromo(Integer promoId) {

        PromoDO promoDO = promoDOMapper.selectByPrimaryKey(promoId);

        System.out.println("PromoDO promoDO = promoDOMapper.selectByPrimaryKey(promoId);\n" +
                "        " + promoDO.getPromoName());

        if (promoDO == null || promoDO.getItemId().intValue() == 0) {
            return;
        }

        ItemModel itemModel = itemService.getItemById(promoDO.getItemId());


        /*这个地方发布活动  我们将活动的所发布的商品的内存发布到redis中*/
        /*1、如果遇到紧急直接删除活动在redis中的字段*/
        /*2、可以更改活动的时间*/
        /*这样这个活动就被下架了*/
        redisTemplate.opsForValue().set("promo_item_stock_" + itemModel.getId(), itemModel.getStock());

        /*放出的库存是这个真是库存的五倍*/
        redisTemplate.opsForValue().set("promo_door_count_" + promoId, itemModel.getStock().intValue() * 5);

    }

    @Override
    public String generateSecondKillToken(Integer promoId, Integer itemId, Integer userId) {
        System.out.println("promoId" + promoId);
        System.out.println("itemId" + itemId);
        System.out.println("userId" + userId);

        //判断库中是否已经售罄了   如果已经售罄了 我们就直接返回下单失败  这个地方是判断我们的库存是不是售罄了    是在mq的地方设置的
        if (Boolean.TRUE.equals(redisTemplate.hasKey("promo_item_stock_invalid_" + itemId))) {
            return null;
        }

        PromoDO promoDO = promoDOMapper.selectByPrimaryKey(promoId);

        PromoModel promoModel = convertFromDataObject(promoDO);

        /*首先我们判断一下这个活动和是不是空活动买卖的时间*/
        if (promoModel == null) {
            return null;
        }

        //判断当前时间是否秒杀活动即将开始或正在进行
        if (promoModel.getStartDate().isAfterNow()) {
            promoModel.setStatus(1);
        } else if (promoModel.getEndDate().isBeforeNow()) {
            promoModel.setStatus(3);
        } else {
            promoModel.setStatus(2);
        }

        //判断活动是否正在进行
        if (promoModel.getStatus().intValue() != 2) {
            return null;
        }

        //判断item信息是否存在
        ItemModel itemModel = itemService.getItemByIdInCache(itemId);
        if (itemModel == null) {
            return null;
        }

        //判断用户信息是否存在
        UserModel userModel = userService.getUserByIdInCache(userId);
        if (userModel == null) {
            return null;
        }


        /*这个地方好像要获取秒杀大闸*/
        /*我们设置了一个秒杀的大闸门 是不是把所有的库存都放空了 */
        Long result = redisTemplate.opsForValue().increment("promo_door_count_" + promoId, -1);

        if (result < 0) {
            return null;
        }


        //生成token并且存入redis内并给一个5分钟的有效期
        String token = UUID.randomUUID().toString().replace("-", "");


        redisTemplate.opsForValue().set("promo_token_" + promoId + "_userid_" + userId + "_itemid_" + itemId, token);

        redisTemplate.expire("promo_token_" + promoId + "_userid_" + userId + "_itemid_" + itemId, 5, TimeUnit.MINUTES);

        return token;
    }

    /**
     * dataproject -> model
     */
    private PromoModel convertFromDataObject(PromoDO promoDO) {
        if (promoDO == null) {
            return null;
        }

        PromoModel promoModel = new PromoModel();
        BeanUtils.copyProperties(promoDO, promoModel);

        promoModel.setPromoItemPrice(new BigDecimal(promoDO.getPromoItemPrice()));
        promoModel.setStartDate(new DateTime(promoDO.getStartDate()));
        promoModel.setEndDate(new DateTime(promoDO.getEndDate()));

        return promoModel;
    }

}
